package referenceimpl

import (
	"context"
	"fmt"

	"gitee.com/leonscript/sally/v2/domain/aggregate"
	"gitee.com/leonscript/sally/v2/domain/entity"
	"gitee.com/leonscript/sally/v2/infrastructure"
	"gitee.com/leonscript/sally/v2/infrastructure/persistent"
	"gitee.com/leonscript/sally/v2/infrastructure/utils"
	"github.com/bytedance/sonic"

	"gorm.io/gorm"
)

type ClerkReferenceImpl struct {
	db *gorm.DB
}

func NewClerkReferenceImpl(db *gorm.DB) aggregate.Reference {
	return &ClerkReferenceImpl{db: db}
}

func (c *ClerkReferenceImpl) QueryWorkflowTemplateByID(ctx context.Context, id string) (result entity.WorkflowTemplate, err error) {
	client := persistent.NewWorkflowTemplateClient(c.db)
	workflowTemplatePO, err := client.QueryWorkflowTemplateByID(ctx, id)
	if err != nil {
		return result, err
	}

	if err = utils.StructCopy(ctx, &result, &workflowTemplatePO); err != nil {
		return result, err
	}

	return result, err
}

// CreateWorkflowTemplateTX 创建工作流模板
// 功能: 在事务中创建工作流模板，通过mapper层进行数据库操作
// 参数:
//
//	ctx: 上下文
//	workflowTemplate: 工作流模板实体
//	tx: 数据库事务
//
// 返回值:
//
//	err: 错误信息
func (c *ClerkReferenceImpl) CreateWorkflowTemplateTX(ctx context.Context, workflowTemplate entity.WorkflowTemplate, tx *gorm.DB) (err error) {
	// 步骤1: 实体转换为PO
	var workflowTemplatePO persistent.WorkflowTemplate
	if err = utils.StructCopy(ctx, &workflowTemplatePO, &workflowTemplate); err != nil {
		return err
	}

	// 步骤2: 通过mapper层进行持久化保存
	client := persistent.NewWorkflowTemplateClient(c.db)
	return client.CreateTX(ctx, workflowTemplatePO, tx)
}

func (c *ClerkReferenceImpl) CreateWorkflowTX(ctx context.Context, workflow entity.Workflow, tx *gorm.DB) (err error) {
	// workflow实体转换为PO
	var workflowPO persistent.Workflow
	if err = utils.StructCopy(ctx, &workflowPO, &workflow); err != nil {
		return err
	}

	// 持久化保存
	client := persistent.NewWorkflowClient(c.db)
	if err = client.CreateTX(ctx, workflowPO, tx); err != nil {
		return err
	}

	return err
}

func (c *ClerkReferenceImpl) CreateNodeTX(ctx context.Context, node entity.Node, tx *gorm.DB) (err error) {
	var nodePO persistent.Node
	if err = utils.StructCopy(ctx, &nodePO, &node); err != nil {
		return err
	}

	client := persistent.NewNodeClient(c.db)
	if err = client.CreateTX(ctx, nodePO, tx); err != nil {
		return err
	}

	return err
}

// CreateNodeTemplateTX 创建节点模板
// 功能: 在事务中创建节点模板，通过mapper层进行数据库操作
// 参数:
//
//	ctx: 上下文
//	nodeTemplate: 节点模板实体
//	tx: 数据库事务
//
// 返回值:
//
//	err: 错误信息
func (c *ClerkReferenceImpl) CreateNodeTemplateTX(ctx context.Context, nodeTemplate entity.NodeTemplate, tx *gorm.DB) (err error) {
	// 步骤1: 实体转换为PO
	var nodeTemplatePO persistent.NodeTemplate
	if err = utils.StructCopy(ctx, &nodeTemplatePO, &nodeTemplate); err != nil {
		return err
	}

	// 步骤2: 序列化条件规则
	conditionRulesBytes, err := sonic.Marshal(nodeTemplate.ConditionRules)
	if err != nil {
		return err
	}
	nodeTemplatePO.ConditionsRaw = string(conditionRulesBytes)

	// 步骤3: 设置BusinessParams
	nodeTemplatePO.BusinessParams = nodeTemplate.BusinessParams

	// 步骤4: 通过mapper层进行持久化保存
	client := persistent.NewNodeTemplateClient(c.db)
	return client.CreateTX(ctx, nodeTemplatePO, tx)
}

// CreateNodeTemplateReviewersTX 批量创建节点模板审批者
func (c *ClerkReferenceImpl) CreateNodeTemplateReviewersTX(ctx context.Context, reviewers []entity.NodeTemplateReviewer, tx *gorm.DB) (err error) {
	if len(reviewers) == 0 {
		return nil
	}

	// 实体转换为PO
	reviewerPOs, err := utils.ArrayCopy(ctx, persistent.NodeTemplateReviewer{}, reviewers)
	if err != nil {
		return err
	}

	// 批量保存
	client := persistent.NewNodeTemplateReviewerClient(c.db)
	return client.BatchCreateTX(ctx, tx, reviewerPOs...)
}

func (c *ClerkReferenceImpl) CreateReviewerTasksTX(ctx context.Context, reviewerTasks []entity.NodeReviewerTask, tx *gorm.DB) (err error) {
	client := persistent.NewNodeReviewerTaskClient(c.db)
	taskPOs, err := utils.ArrayCopy(ctx, persistent.NodeReviewerTask{}, reviewerTasks)
	if err != nil {
		return err
	}

	// 创建
	return client.BatchCreateTX(ctx, tx, taskPOs...)
}

func (c *ClerkReferenceImpl) QueryReviewerTaskByID(ctx context.Context, id string) (result entity.NodeReviewerTask, err error) {
	client := persistent.NewNodeReviewerTaskClient(c.db)
	reviewerTaskPO, err := client.QueryReviewerTaskByID(ctx, id)
	if err != nil {
		return result, err
	}
	if err = utils.StructCopy(ctx, &result, &reviewerTaskPO); err != nil {
		return result, err
	}
	return result, err
}

func (c *ClerkReferenceImpl) QueryNodeReviewerTasksByNodeIDTX(ctx context.Context, nodeID string, tx *gorm.DB) (result []entity.NodeReviewerTask, err error) {
	client := persistent.NewNodeReviewerTaskClient(c.db)
	reviewerTaskPOs, err := client.QueryByNodeIDTX(ctx, nodeID, tx)
	if err != nil {
		return result, err
	}
	for _, po := range reviewerTaskPOs {
		var task entity.NodeReviewerTask
		if err = utils.StructCopy(ctx, &task, &po); err != nil {
			return result, err
		}
		result = append(result, task)
	}
	return result, err
}

func (c *ClerkReferenceImpl) QueryAndLockWorkflowByCondTX(ctx context.Context, cond aggregate.QueryWorkflowCond, tx *gorm.DB) (result entity.Workflow, err error) {
	client := persistent.NewWorkflowClient(c.db)
	// 查询workflow
	workflowPO, err := client.QueryWorkflowByCondTX(ctx, cond, tx)
	if err != nil {
		return result, err
	}

	// workflow上锁
	_, err = client.LockTX(ctx, workflowPO.ID, tx)
	if err != nil {
		return result, err
	}

	// PO转换为实体
	err = utils.StructCopy(ctx, &result, &workflowPO)
	if err != nil {
		return result, err
	}

	return result, err
}

func (c *ClerkReferenceImpl) QueryNodeTemplateByID(ctx context.Context, id string) (result entity.NodeTemplate, err error) {
	client := persistent.NewNodeTemplateClient(c.db)
	nodeTemplatePO, err := client.QueryNodeTemplateByID(ctx, id)
	if err != nil {
		return result, err
	}

	// 转换为实体
	if err = utils.StructCopy(ctx, &result, &nodeTemplatePO); err != nil {
		return result, err
	}

	// 设置BusinessParams
	result.BusinessParams = nodeTemplatePO.BusinessParams

	return result, sonic.Unmarshal([]byte(nodeTemplatePO.ConditionsRaw), &result.ConditionRules)
}

func (c *ClerkReferenceImpl) UpdateWorkflow(ctx context.Context, workflow entity.Workflow) (err error) {
	client := persistent.NewWorkflowClient(c.db)
	var workflowPO persistent.Workflow
	if err = utils.StructCopy(ctx, &workflowPO, &workflow); err != nil {
		return err
	}

	return client.Update(ctx, workflowPO)
}
func (c *ClerkReferenceImpl) UpdateWorkflowTX(ctx context.Context, workflow entity.Workflow, tx *gorm.DB) (err error) {
	client := persistent.NewWorkflowClient(c.db)
	var workflowPO persistent.Workflow
	if err = utils.StructCopy(ctx, &workflowPO, &workflow); err != nil {
		return err
	}

	return client.UpdateTX(ctx, workflowPO, tx)
}

func (c *ClerkReferenceImpl) UpdateNodeTX(ctx context.Context, node entity.Node, tx *gorm.DB) (err error) {
	client := persistent.NewNodeClient(c.db)
	var nodePO persistent.Node
	if err = utils.StructCopy(ctx, &nodePO, &node); err != nil {
		return err
	}

	return client.UpdateTX(ctx, nodePO, tx)
}

func (c *ClerkReferenceImpl) QueryNodeTemplateReviewers(ctx context.Context, nodeTemplateID string) (result []entity.NodeTemplateReviewer, err error) {
	client := persistent.NewNodeTemplateReviewerClient(c.db)
	reviewers, err := client.QueryReviewersByNodeTemplateID(ctx, nodeTemplateID)
	if err != nil {
		return result, err
	}

	return utils.ArrayCopy(ctx, entity.NodeTemplateReviewer{}, reviewers)
}

func (c *ClerkReferenceImpl) QueryNodeByIDTX(ctx context.Context, id string, tx *gorm.DB) (result entity.Node, err error) {
	client := persistent.NewNodeClient(c.db)
	nodePO, err := client.QueryNodeByIDTX(ctx, id, tx)
	if err != nil {
		return result, err
	}

	err = utils.StructCopy(ctx, &result, &nodePO)
	return result, err
}

func (c *ClerkReferenceImpl) UpdateNodeReviewerTaskTX(ctx context.Context, nodeReviewerTask entity.NodeReviewerTask, tx *gorm.DB) (err error) {
	client := persistent.NewNodeReviewerTaskClient(c.db)
	var nodeReviewerTaskPO persistent.NodeReviewerTask
	if err = utils.StructCopy(ctx, &nodeReviewerTaskPO, &nodeReviewerTask); err != nil {
		return err
	}

	return client.UpdateTX(ctx, nodeReviewerTaskPO, tx)
}

func (c *ClerkReferenceImpl) UpdateNodeReviewerTaskByCondTX(ctx context.Context, cond, nodeReviewerTask entity.NodeReviewerTask, tx *gorm.DB) (err error) {
	client := persistent.NewNodeReviewerTaskClient(c.db)
	// 构建条件
	var condPO persistent.NodeReviewerTask
	if err = utils.StructCopy(ctx, &condPO, &cond); err != nil {
		return err
	}

	// 构建修改值
	var nodeReviewerTaskPO persistent.NodeReviewerTask
	if err = utils.StructCopy(ctx, &nodeReviewerTaskPO, &nodeReviewerTask); err != nil {
		return err
	}

	// 执行更新
	return client.UpdateByCondTX(ctx, condPO, nodeReviewerTaskPO, tx)
}

func (c *ClerkReferenceImpl) QueryActivatedWorkflows(ctx context.Context, req aggregate.GetWorkflowsRequest) (result []aggregate.ActivatedWorkflow, total int64, err error) {
	client := persistent.NewActivatedWorkflowClient(c.db)
	activatedWorkflowPOs, total, err := client.QueryActivatedWorkflows(ctx, req)
	if err != nil {
		return result, total, err
	}

	result, err = utils.ArrayCopy(ctx, aggregate.ActivatedWorkflow{}, activatedWorkflowPOs)
	if err != nil {
		return result, total, err
	}

	// 数据转换
	result, err = c.getActivatedWorkflows(activatedWorkflowPOs)

	return result, total, err
}

func (c *ClerkReferenceImpl) QueryWorkflowByID(ctx context.Context, id string) (result entity.Workflow, err error) {
	client := persistent.NewWorkflowClient(c.db)
	workflowPO, err := client.QueryWorkflowByID(id)
	if err != nil {
		return result, err
	}

	// PO转为实体
	if err = utils.StructCopy(ctx, &result, &workflowPO); err != nil {
		return result, err
	}

	return result, err
}

func (c *ClerkReferenceImpl) QueryNodeReviewTasks(ctx context.Context, req aggregate.GetNodeReviewTasksRequest) (result []aggregate.NodeReviewTask, total int64, err error) {
	client := persistent.NewNodeReviewTaskClient(c.db)
	taskPOs, total, err := client.QueryNodeReviewTasks(ctx, req)
	if err != nil {
		return result, total, err
	}

	// 手动转换，处理Comment字段的特殊转换
	for _, taskPO := range taskPOs {
		var task aggregate.NodeReviewTask
		if err = utils.StructCopy(ctx, &task, &taskPO); err != nil {
			return result, total, err
		}
		// 特殊处理Comment字段：从JSON字符串转换为BusinessParams
		if taskPO.Comment != "" {
			task.Comment, err = aggregate.NewBusinessParams(taskPO.Comment)
			if err != nil {
				return result, total, err
			}
		} else {
			task.Comment = aggregate.BusinessParams{}
		}

		// 特殊处理NodeBusinessParams字段：从JSON字符串转换为BusinessParams
		if taskPO.NodeBusinessParams != "" {
			task.NodeBusinessParams, err = aggregate.NewBusinessParams(taskPO.NodeBusinessParams)
			if err != nil {
				return result, total, err
			}
		} else {
			task.NodeBusinessParams = aggregate.BusinessParams{}
		}
		result = append(result, task)
	}
	return result, total, err
}

func (c *ClerkReferenceImpl) QueryNodeReviewTasksTX(ctx context.Context, req aggregate.GetNodeReviewTasksRequest, tx *gorm.DB) (result []aggregate.NodeReviewTask, err error) {
	client := persistent.NewNodeReviewTaskClient(c.db)
	taskPOs, err := client.QueryNodeReviewTasksTX(ctx, req, tx)
	if err != nil {
		return result, err
	}

	// 手动转换，处理Comment字段的特殊转换
	for _, taskPO := range taskPOs {
		var task aggregate.NodeReviewTask
		if err = utils.StructCopy(ctx, &task, &taskPO); err != nil {
			return result, err
		}
		// 特殊处理Comment字段：从JSON字符串转换为BusinessParams
		if taskPO.Comment != "" {
			task.Comment, err = aggregate.NewBusinessParams(taskPO.Comment)
			if err != nil {
				return result, err
			}
		} else {
			task.Comment = aggregate.BusinessParams{}
		}
		result = append(result, task)
	}
	return result, err
}

func (c *ClerkReferenceImpl) DeleteWorkflowByCondTX(ctx context.Context, id string, tx *gorm.DB) (err error) {
	return persistent.NewWorkflowClient(c.db).DeleteWorkflowByCondTX(ctx, id, tx)
}

func (c *ClerkReferenceImpl) DeleteNodeByCondTX(ctx context.Context, workflowID string, tx *gorm.DB) (err error) {
	return persistent.NewNodeClient(c.db).DeleteNodeByCondTX(ctx, workflowID, tx)
}

func (c *ClerkReferenceImpl) DeleteNodeReviewerTaskByCondTX(ctx context.Context, workflowID string, tx *gorm.DB) (err error) {
	// 查询workflow下的节点
	nodes, err := persistent.NewNodeClient(c.db).QueryNodesByCondTX(ctx, persistent.Node{WorkflowID: workflowID}, tx)
	if err != nil {
		return err
	}

	// 删除任务
	return c.deleteReviewerTaskByNodePOs(ctx, nodes, tx)
}

func (c *ClerkReferenceImpl) Begin() *gorm.DB {
	return c.db.Begin()
}

func (c *ClerkReferenceImpl) Commit(tx *gorm.DB) error {
	return tx.Commit().Error
}

func (c *ClerkReferenceImpl) Rollback(tx *gorm.DB) error {
	return tx.Rollback().Error
}

func (c *ClerkReferenceImpl) getActivatedWorkflows(activatedWorkflowPOs []persistent.ActivatedWorkflow) (result []aggregate.ActivatedWorkflow, err error) {
	for _, activatedWorkflowPO := range activatedWorkflowPOs {
		activatedWorkflow := aggregate.ActivatedWorkflow{
			CreatedAt:             activatedWorkflowPO.CreatedAt,
			CurrentNodeID:         activatedWorkflowPO.CurrentNodeID,
			CurrentNodeName:       activatedWorkflowPO.CurrentNodeName,
			CurrentNodeTemplateID: activatedWorkflowPO.CurrentNodeTemplateID,
			FormContent:           activatedWorkflowPO.FormContent,
			Conclusion:            activatedWorkflowPO.Conclusion,
			ID:                    activatedWorkflowPO.ID,
			Name:                  activatedWorkflowPO.Name,
			Status:                activatedWorkflowPO.Status,
			UpdatedAt:             activatedWorkflowPO.UpdatedAt,
			BusinessID:            activatedWorkflowPO.BusinessID,
			BusinessCode:          activatedWorkflowPO.BusinessCode,
			SponsorID:             activatedWorkflowPO.SponsorID,
		}
		activatedWorkflow.BusinessParams, err = aggregate.NewBusinessParams(activatedWorkflowPO.BusinessParams)
		if err != nil {
			return result, err
		}
		result = append(result, activatedWorkflow)
	}

	return result, nil
}

// QueryTimeoutNodes 查询所有超时的节点
// 功能说明:
//  1. 查询所有超时的节点信息
//  2. 返回超时节点的基本信息
//
// 参数说明:
//   - ctx: 上下文对象
//
// 返回值:
//   - result: 超时节点信息列表
//   - err: 查询过程中的错误信息
func (c *ClerkReferenceImpl) QueryTimeoutNodes(ctx context.Context) (result []aggregate.TimeoutNodeInfo, err error) {
	client := persistent.NewTimeoutNodesClient(c.db)
	timeoutNodes, err := client.QueryTimeoutNodes(ctx)
	if err != nil {
		return result, err
	}

	// 转换为aggregate类型
	return utils.ArrayCopy(ctx, aggregate.TimeoutNodeInfo{}, timeoutNodes)
}

// QueryTimeoutNodesWithTasks 查询所有超时的节点及其审批任务
// 功能说明:
//  1. 通过一次查询获取所有超时节点及其相关的审批任务信息
//  2. 避免N+1查询问题，提升查询性能
//  3. 查询条件与QueryTimeoutNodes相同，但同时获取审批任务数据
//
// 参数说明:
//   - ctx: 上下文对象
//
// 返回值:
//   - result: 超时节点及审批任务信息列表
//   - err: 查询过程中的错误信息
func (c *ClerkReferenceImpl) QueryTimeoutNodesWithTasks(ctx context.Context) (result []aggregate.TimeoutNodeWithTasks, err error) {
	client := persistent.NewTimeoutNodesClient(c.db)
	timeoutNodesWithTasks, err := client.QueryTimeoutNodesWithTasks(ctx)
	if err != nil {
		return nil, err
	}

	// 转换为aggregate类型
	return utils.ArrayCopy(ctx, aggregate.TimeoutNodeWithTasks{}, timeoutNodesWithTasks)
}

// QueryNodeTemplateReviewersByNodeTemplateIDs 根据节点模板ID列表批量查询所有审批人
func (c *ClerkReferenceImpl) QueryNodeTemplateReviewersByNodeTemplateIDs(ctx context.Context, nodeTemplateIDs []string) (result []entity.NodeTemplateReviewer, err error) {
	if len(nodeTemplateIDs) == 0 {
		return result, nil
	}

	client := persistent.NewNodeTemplateReviewerClient(c.db)
	reviewers, err := client.QueryReviewersByNodeTemplateIDs(ctx, nodeTemplateIDs)
	if err != nil {
		return nil, err
	}

	// 转换为entity
	for _, reviewer := range reviewers {
		entityReviewer := entity.NodeTemplateReviewer{
			ID:             reviewer.ID,
			Kind:           reviewer.Kind,
			NodeTemplateID: reviewer.NodeTemplateID,
			ReviewerNos:    reviewer.ReviewerNos,
			ReviewerIDs:    reviewer.ReviewerIDs,
		}
		result = append(result, entityReviewer)
	}

	return result, nil
}

func (c *ClerkReferenceImpl) deleteReviewerTaskByNodePOs(ctx context.Context, nodes []persistent.Node, tx *gorm.DB) (err error) {
	var nodeIDs []string
	for _, node := range nodes {
		nodeIDs = append(nodeIDs, node.ID)
	}

	return persistent.NewNodeReviewerTaskClient(c.db).DeleteNodeReviewerTaskByCondTX(ctx, nodeIDs, tx)
}

// QueryNodeReviewerTaskByIDTX 根据任务ID查询审批任务（事务版本）
func (c *ClerkReferenceImpl) QueryNodeReviewerTaskByIDTX(ctx context.Context, id string, tx *gorm.DB) (result entity.NodeReviewerTask, err error) {
	client := persistent.NewNodeReviewerTaskClient(c.db)
	reviewerTaskPO, err := client.QueryReviewerTaskByIDTX(ctx, id, tx)
	if err != nil {
		return result, err
	}
	if err = utils.StructCopy(ctx, &result, &reviewerTaskPO); err != nil {
		return result, err
	}
	return result, err
}

// QueryNodeTemplatesByWorkflowTemplateID 根据工作流模板ID查询所有节点模板
func (c *ClerkReferenceImpl) QueryNodeTemplatesByWorkflowTemplateID(ctx context.Context, workflowTemplateID string) (result []entity.NodeTemplate, err error) {
	client := persistent.NewNodeTemplateClient(c.db)
	nodeTemplatePOs, err := client.QueryNodeTemplatesByWorkflowTemplateID(ctx, workflowTemplateID)
	if err != nil {
		return result, err
	}

	for _, nodeTemplatePO := range nodeTemplatePOs {
		var nodeTemplate entity.NodeTemplate
		if err = utils.StructCopy(ctx, &nodeTemplate, &nodeTemplatePO); err != nil {
			return result, err
		}

		// 反序列化条件规则
		if nodeTemplatePO.ConditionsRaw != "" {
			var conditionRules []entity.ConditionRule
			if err = sonic.Unmarshal([]byte(nodeTemplatePO.ConditionsRaw), &conditionRules); err != nil {
				return result, fmt.Errorf("反序列化条件规则失败: %w", err)
			}
			nodeTemplate.ConditionRules = conditionRules
		}

		result = append(result, nodeTemplate)
	}

	return result, nil
}

// QueryNodesByWorkflowID 根据工作流ID查询所有节点
func (c *ClerkReferenceImpl) QueryNodesByWorkflowID(ctx context.Context, workflowID string) (result []entity.Node, err error) {
	client := persistent.NewNodeClient(c.db)
	nodes, err := client.QueryNodesByWorkflowID(ctx, workflowID)
	if err != nil {
		return nil, err
	}

	for _, node := range nodes {
		result = append(result, entity.Node{
			ID:             node.ID,
			Status:         node.Status,
			WorkflowID:     node.WorkflowID,
			NodeTemplateID: node.NodeTemplateID,
			CreatedAt:      node.CreatedAt,
			UpdatedAt:      node.UpdatedAt,
		})
	}

	return result, nil
}

// FindNextApprovalNodeRecursive 递归查找下一个审批节点
// 从指定的节点模板开始，根据条件参数递归查找下一个需要审批的节点模板
// 参数:
//   - ctx: 上下文对象
//   - currentNodeTemplateID: 当前节点模板ID
//   - conditionParams: 条件参数，用于条件路由判断
//   - visitedNodes: 已访问的节点集合，用于循环引用检测
//   - depth: 当前递归深度
//   - maxDepth: 最大递归深度限制
//
// 返回值:
//   - nextNodeTemplateID: 下一个审批节点模板ID，空字符串表示已到达工作流末尾
//   - err: 错误信息
func (c *ClerkReferenceImpl) FindNextApprovalNodeRecursive(ctx context.Context, currentNodeTemplateID string, conditionParams entity.ConditionParams, visitedNodes map[string]bool, depth, maxDepth int) (nextNodeTemplateID string, err error) {
	// 步骤1: 递归深度检查，防止无限递归
	if depth >= maxDepth {
		return "", fmt.Errorf("递归深度超过限制: %d", maxDepth)
	}

	// 步骤2: 循环引用检测，防止死循环
	if visitedNodes[currentNodeTemplateID] {
		return "", fmt.Errorf("检测到循环引用: 节点 %s 已被访问", currentNodeTemplateID)
	}

	// 步骤3: 标记当前节点为已访问
	visitedNodes[currentNodeTemplateID] = true

	// 步骤4: 查询当前节点模板
	currentNode, err := c.QueryNodeTemplateByID(ctx, currentNodeTemplateID)
	if err != nil {
		return "", fmt.Errorf("查询节点模板失败: %w", err)
	}

	// 步骤5: 根据节点类型进行不同的处理
	switch currentNode.Kind {
	case entity.NodeTemplateKindApproval: // 审批节点
		// 找到审批节点，返回当前节点ID
		return currentNodeTemplateID, nil

	case entity.NodeTemplateKindCondition: // 条件节点
		// 评估条件，获取下一个节点ID
		nextNodeID := currentNode.EvaluateNodeConditions(conditionParams)
		if nextNodeID == "" {
			// 没有匹配的条件，返回自定义错误类型
			return "", infrastructure.NewErrConditionNotMet()
		}
		// 递归查找下一个节点
		return c.FindNextApprovalNodeRecursive(ctx, nextNodeID, conditionParams, visitedNodes, depth+1, maxDepth)

	case entity.NodeTemplateKindStart: // 开始节点
		// 开始节点直接跳转到下一个节点
		if currentNode.NextNodeTemplateID == "" {
			// 没有下一个节点，工作流结束
			return "", nil
		}
		// 递归查找下一个节点
		return c.FindNextApprovalNodeRecursive(ctx, currentNode.NextNodeTemplateID, conditionParams, visitedNodes, depth+1, maxDepth)

	case entity.NodeTemplateKindEnd: // 结束节点
		// 到达结束节点，工作流结束
		return "", nil

	default:
		// 未知节点类型，按照普通节点处理
		return "", fmt.Errorf("未知节点类型: %d", currentNode.Kind)
	}
}

// CheckTimeoutAlertRecords 批量检查节点是否已发送提醒
// 查询指定工作流下的节点提醒记录状态
// 参数:
//   - ctx: 上下文
//   - nodeIDs: 节点ID列表
//   - workflowID: 工作流ID
//
// 返回值:
//   - result: 节点ID到是否已提醒的映射，true表示已提醒
//   - err: 错误信息
func (c *ClerkReferenceImpl) CheckTimeoutAlertRecords(ctx context.Context, nodeIDs []string, workflowID string) (result map[string]bool, err error) {
	// 实现步骤：
	// 1. 创建超时提醒记录客户端
	// 2. 调用客户端方法查询提醒记录
	// 3. 返回查询结果

	client := persistent.NewTimeoutAlertRecordClient(c.db)
	return client.CheckAlertRecords(nodeIDs, workflowID)
}

// CreateTimeoutAlertRecord 创建超时提醒记录
// 使用UPSERT方式创建或更新提醒记录，确保幂等性
// 参数:
//   - ctx: 上下文
//   - nodeID: 节点ID
//   - workflowID: 工作流ID
//
// 返回值:
//   - err: 错误信息
func (c *ClerkReferenceImpl) CreateTimeoutAlertRecord(ctx context.Context, nodeID, workflowID string) (err error) {
	// 实现步骤：
	// 1. 创建超时提醒记录客户端
	// 2. 调用客户端方法创建提醒记录
	// 3. 返回操作结果

	client := persistent.NewTimeoutAlertRecordClient(c.db)
	return client.CreateAlertRecord(nodeID, workflowID)
}

// BatchCreateTimeoutAlertRecords 批量创建超时提醒记录
// 批量插入多个节点的提醒记录，提高性能
// 参数:
//   - ctx: 上下文
//   - nodeIDs: 节点ID列表
//   - workflowID: 工作流ID
//
// 返回值:
//   - err: 错误信息
func (c *ClerkReferenceImpl) BatchCreateTimeoutAlertRecords(ctx context.Context, nodeIDs []string, workflowID string) (err error) {
	// 实现步骤：
	// 1. 创建超时提醒记录客户端
	// 2. 调用客户端方法批量创建提醒记录
	// 3. 返回操作结果

	client := persistent.NewTimeoutAlertRecordClient(c.db)
	return client.BatchCreateAlertRecords(nodeIDs, workflowID)
}
